from quant import utils


class Logging:
    CRITICAL = 0
    ERROR = 1
    WARN = 2
    INFO = 3

    def __init__(self):
        self.event_engine = utils.EventEngine()

    def info(self, msg):
        self.event_engine.put(self.INFO, msg)

    def warn(self, msg):
        self.event_engine.put(self.WARN, msg)

    def error(self, msg):
        self.event_engine.put(self.ERROR, msg)

    def critical(self, msg):
        self.event_engine.put(self.CRITICAL, msg)

    def set_level(self, level=-1):
        for i in range(4):
            self.event_engine.unsubscribe(i, print_msg)
        for i in range(level+1):
            self.event_engine.subscribe(i, print_msg)

    def subscribe(self, handler, level=None):
        if level is None:
            lvs = [self.CRITICAL, self.ERROR, self.WARN, self.INFO]
        else:
            lvs = [level]
        for lv in lvs:
            self.event_engine.subscribe(lv, handler)

    def unsubscribe(self, handler, level):
        self.event_engine.unsubscribe(level, handler)


class LoggingSaver:
    _line_log = None

    def __init__(self, path=None, file_hours=24, keep_hours=48):

        self._path = path
        self._file_minutes = file_hours * 60
        self._keep_hours = keep_hours
        self.init()

    def init(self):
        from quant.utils import LineLog2

        fields = ['info', 'warning', 'error', 'critical']
        self._line_log: LineLog2 = LineLog2('logging', fields, self._path, self._file_minutes, self._keep_hours)

        logging.subscribe(self.on_info, logging.INFO)
        logging.subscribe(self.on_warning, logging.WARN)
        logging.subscribe(self.on_error, logging.ERROR)
        logging.subscribe(self.on_critical, logging.CRITICAL)

    def on_info(self, msg):
        self._line_log.log_value('info', msg)

    def on_warning(self, msg):
        self._line_log.log_value('warning', msg)

    def on_error(self, msg):
        self._line_log.log_value('error', msg)

    def on_critical(self, msg):
        self._line_log.log_value('critical', msg)

    def save(self):
        self._line_log.save()


class ErrorLoggingSaver(LoggingSaver):
    def init(self):
        from quant.utils import LineLog2

        fields = ['error', 'critical']
        self._line_log: LineLog2 = LineLog2('error_logging', fields, self._path, self._file_minutes, self._keep_hours)

        logging.subscribe(logging.ERROR, self.on_error)
        logging.subscribe(logging.CRITICAL, self.on_critical)


def print_msg(msg):
    print('logging:', msg)


logging = Logging()


if __name__ == '__main__':
    def __test_level():
        logging.set_level(logging.ERROR)
        logging.info('info1')
        logging.warn('warn1')
        logging.error('error1')
        logging.critical('critical1')
        logging.set_level(logging.CRITICAL)
        logging.info('info2')
        logging.warn('warn2')
        logging.error('error2')
        logging.critical('critical2')
        logging.set_level()
        logging.info('info3')
        logging.warn('warn3')
        logging.error('error3')
        logging.critical('critical3')

    def __test_subscribe():
        def fn(msg):
            print(msg)

        def fn2(msg):
            print(2, msg)

        logging.add_handler(logging.ERROR, fn)
        logging.info('info1')
        logging.warn('warn1')
        logging.error('error1')
        logging.critical('critical1')
        logging.remove_handler(logging.ERROR, fn)
        logging.info('inf2')
        logging.warn('war2')
        logging.error('erro2')
        logging.critical('critica2')
        logging.add_handler(logging.ERROR, fn)
        logging.add_handler(logging.ERROR, fn2)
        logging.info('inf3')
        logging.warn('war3')
        logging.error('erro3')
        logging.critical('critica3')

    def __test_saver():
        a = LoggingSaver('.')
        b = ErrorLoggingSaver('.')

        logging.error('err1')
        logging.error('err2')
        logging.warn('warn1')
        logging.warn('warn2')
        logging.info('info1')
        logging.info('info2')
        logging.critical('cri1')
        logging.critical('cri2')
        input(':')
        a.save()
        b.save()
        input(':')

    # __test_subscribe()
    __test_saver()

















